The ONE所支持的移动模型movement,实际是以某种规则产生一系列连接建立或撤消的事件。本文介绍连接事件的读取和事件处理。连接事件在初始化时预读取500个,待到处理完后再读取500个,如此反复。

1. 概述

The ONE所支持的移动模型movement,实际是以某种规则产生一系列连接建立或撤消的事件,其形式如下:

21574 CONN 1 40 up
21687 CONN 1 40 down

这些事件被加入到事件队列(List<EventQueue> queues),供EventQueueHandler处理,详情可参考博文《宏观角度理解事件是如何组织》。

The ONE所支持的移动模型可以理解成先生成上述格式的文本文件(每一行对应着一个事件),而后The ONE从该文件读取事件。在设置文件my_settings.txt中设置连接事件文件的路径,举例如下:

Events1.class = ExternalEventsQueue 
Events1.filePath = nc/traces_pan/one_infocom06.dat

ConnectionEvent类用来描述一个连接事件,包含如下成员变量(跟Connection类差不多):

protected double time;  //ExternalEvent.java   事件触发时间(单位:秒)

//ConnectionEvent.java
protected String interfaceId;  //the interfaceId number for this event
protected int fromAddr;
protected int toAddr;
protected boolean isUp;     //true为连接建立up,false为连接撤消down

2. 读取事件

2.1 初始化读取

The ONE初始化会创建场景SimScenario()SimScenario()会创建事件队列处理EventQueueHandle实例(用于处理The ONE所有事件),EventQueueHandle构造函数包含如下语句,用于读取500个连接事件,并加入到queues

queues.add(new ExternalEventsQueue(path, preload));  //创建外部事件,并加入到queues

preload是预读取的事件数,可以通过settings文件,修改默认值,如下:

public static final int DEFAULT_NROF_PRELOAD = 500  //ExternalEventsQueue.java

Events1.class = ExternalEventsQueue
Events1.nrofPreload =

ExternalEventsQueue构造函数展开,关键源代码如下:

//ExternalEventsQueue.java
public ExternalEventsQueue(String filePath, int nrofPreload) {
    setNrofPreload(nrofPreload);
    init(filePath);
}

//init(filePath);  private void init(String eeFilePath)
this.reader = new StandardEventsReader(eventsFile);  //StandardEventsReader,实为new BufferedReader(new FileReader(filePath)),为读取文件做准备
this.queue = readEvents(nrofPreload);

//this.queue = readEvents(nrofPreload);
List<ExternalEvent> events = reader.readEvents(nrof);

2.2 后续读取

当初始化读取的500个事件处理完后,再读取500个,如此反复读取。在DTNSim.main –> new DTNSimTextUI().start –> DTNSimTextUI.runSim –> World.update包含如下语句:

//World.java中update()
ExternalEvent ee = this.nextEventQueue.nextEvent();
ee.processEvent(this);

ExternalEventsQueue.java中的nextEvent(),当连接事件处理完后,再读取500个事件,源代码如下:

//ExternalEventsQueue.java中的nextEvent()
public ExternalEvent nextEvent() {
    if (queue.size() == 0) { // no more events
        return new ExternalEvent(Double.MAX_VALUE);
    }

    ExternalEvent ee = queue.get(nextEventIndex);
    nextEventIndex++;

    if (nextEventIndex >= queue.size()) { //ran out of events
        queue = readEvents(nrofPreload);  //再次读取事件
        nextEventIndex = 0;
    }

    return ee;
}

3. 事件处理

处理连接事件很简单,即将连接(实际操作的是网络接口,Interface)标识为建立或撤消,相关源代码如下:

//ConnectionEvent.java
public void processEvent(World world) {
    DTNHost from = world.getNodeByAddress(this.fromAddr);
    DTNHost to = world.getNodeByAddress(this.toAddr);

    from.forceConnection(to, interfaceId, this.isUp);  //建立连接
}

//DTNHost.java中的forceConnection(DTNHost anotherHost, String interfaceId, boolean up)
if (up) {
    ni.createConnection(no);
} else {
    ni.destroyConnection(no);
}
本文系Spark & Shine原创,转载需注明出处本文最近一次修改时间 2022-03-27 15:54

results matching ""

    No results matching ""